<?php
class ModelSaleMailTask extends Model {

	public function addMailTask($data) {
		$store_id = $data['config']['store_id'];
		switch($data['to']) {
			case 'newsletter':
				$items = $this->db->queryOne("SELECT COUNT(*) as total FROM @@customer WHERE newsletter = 1 AND store_id = $store_id");
			break;
			case 'customer_all':
				$items = $this->db->queryOne("SELECT COUNT(*) as total FROM @@customer WHERE store_id = $store_id");
			break;
			case 'customer_group':
				$customer_group_id = $data['config']['customer_group_id'];
				$items = $this->db->queryOne("SELECT COUNT(*) as total FROM @@customer WHERE customer_group_id = $customer_group_id AND store_id = $store_id");
			break;
			case 'customer':
				$items = count($data['config']['customer']);
			break;
			case 'affiliate_all':
				$items = $this->db->queryOne("SELECT COUNT(*) as total FROM @@affiliate");
			break;
			case 'affiliate':
				$items = count($data['config']['affiliate']);
			break;
			case 'product':
				$product_ids = implode(',', $data['config']['product']);
				$items = $this->db->queryOne("SELECT COUNT(DISTINCT customer_id) FROM @@order o INNER JOIN @@order_product op
						WHERE o.order_id = op.order_id AND op.product_id IN ($product_ids)");
			break;
		}
		$data['config'] = serialize($data['config']);
		$data['items'] = $items;
		$data['date_added'] = $GLOBALS['V5_NOW'];
		return $this->db->insert('mail_task', $data);

	}

	public function editMailTask($mail_task_id, $data) {
		return $this->db->update('mail_task', $data, "mail_task_id = $mail_task_id");
	}

	public function getMailTask($mail_task_id) {
		return $this->db->queryOne("SELECT * FROM @@mail_task WHERE mail_task_id = $mail_task_id");
	}

	public function deleteMailTask($mail_task_id) {
		if (is_array($mail_task_id)) $mail_task_id = implode(',', $mail_task_id);
		$this->db->runSql("DELETE FROM @@mail_task WHERE mail_task_id IN ($mail_task_id)");
		$this->db->runSql("DELETE FROM @@mail_taskitem WHERE mail_task_id IN ($mail_task_id)");
	}

	public function getMailTasks($filter = null) {
		$sql = "SELECT mt.*, m.subject FROM @@mail_task mt LEFT JOIN @@mail m ON mt.mail_id = m.mail_id WHERE 1";
		if ($filter) {
			if ($filter->get('filter_title')) {
				$sql .= " AND title LIKE '%" . ES($filter->get('filter_title')) . "%'";
			}
			$sql .= $filter->sort('mail_task_id', 'DESC');
			$sql .= $filter->limit();
		}

		$query = $this->db->query($sql);
		return $query->rows;
	}

	public function getTotalMailTasks($filter = null) {
		$sql = "SELECT COUNT(*) AS total FROM @@mail_task WHERE 1";
		if ($filter) {
			if ($filter->get('filter_title')) {
				$sql .= " AND title LIKE '%" . ES($filter->get('filter_title')) . "%'";
			}
		}
		return $this->db->queryOne($sql);
	}
	
	public function send($mail_task_id) {
		$task = $this->db->queryOne("SELECT * FROM @@mail_task WHERE mail_task_id=$mail_task_id");
		if ($task['status'] == 2) {//had finished
			return $task;
		}
		
		if ($task['status'] == 0) { //first run, init first
			$count = $this->initTask($task);
			if ($count != $task['items']) {
				$task['items'] = $count;
			}
			$this->db->runSql("UPDATE @@mail_task SET items={$task['items']}, status=1 WHERE mail_task_id=$mail_task_id");
			return $task;
		}
		
		//send mail
		$query = $this->db->query("SELECT mail_taskitem_id, email FROM @@mail_taskitem WHERE status=0 AND mail_task_id=$mail_task_id LIMIT 5");
		$task_status = 1;
		$task_sent = 0;
		$task_errors = 0;
		if ($query->num_rows) {
			if ($query->num_rows < 5) $task_status = 2;
			$mail_content = $this->db->queryOne("SELECT * FROM @@mail WHERE mail_id = {$task['mail_id']}");
			
			$config = unserialize($task['config']);
			$store_id = $config['store_id'];
			M('setting/store');
			$store_info = $this->model_setting_store->getStore($store_id);			
			if ($store_info) {
				$store_name = $store_info['name'];
			} else {
				$store_name = C('config_name');
			}
			
			$mail = new Mail();
			$mail->protocol = C('config_mail_protocol');
			$mail->parameter = C('config_mail_parameter');
			$mail->hostname = C('config_smtp_host');
			$mail->username = C('config_smtp_username');
			$mail->password = C('config_smtp_password');
			$mail->port = C('config_smtp_port');
			$mail->timeout = C('config_smtp_timeout');
			$mail->auto_close = false;
			$mail->setFrom(C('config_email'));
			$mail->setSender($store_name);
			$mail->setSubject(v5_html_entity_decode($mail_content['subject']));
			
			$message  = '<html>' . "\n";
			$message .= '  <head>' . "\n";
			$message .= '    <title>' . $mail_content['subject'] . '</title>' . "\n";
			$message .= '    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">' . "\n";
			$message .= '  </head>' . "\n";
			$message .= '  <body>' . v5_html_entity_decode($mail_content['content']) . "\n";
			$message .= '<div style="display:none"><img width="0" height="0" src="'. U('common/track/mail', 'code={TRACKCODE}') .'" alt="" /></div>';
			$message .= '</body></html>' . "\n";
			
			foreach ($query->rows as $row) {
				$mail->setTo($row['email']);
				$track_code = encrypt($row['mail_taskitem_id']);
				$html = str_replace('{TRACKCODE}', $track_code, $message);
				$mail->setHtml($html);
				if($mail->send()) {
					$this->db->runSql("UPDATE @@mail_taskitem SET date_sent='{$GLOBALS['V5_NOW']}', status=2 WHERE mail_taskitem_id = {$row['mail_taskitem_id']}");
					$task_sent++;
				}
				else {
					$this->db->runSql("UPDATE @@mail_taskitem SET date_sent='{$GLOBALS['V5_NOW']}', status=1, note = '".ES($mail->error)."' WHERE mail_taskitem_id = {$row['mail_taskitem_id']}");
					$task_errors++;
					break;
				}
				
				$mail->reset();
				sleep(2);
			}
			$mail->close();
		}
		else {
			$task_status = 2;
		}
		
		if ($task['items'] <= ($task['sent'] + $task_sent)) $task_status = 2;
		
		$this->db->runSql("UPDATE @@mail_task SET sent = sent + $task_sent, errors = errors + $task_errors, status = $task_status
				WHERE mail_task_id = $mail_task_id");
		
		if ($task_errors) {
			return false;
		}
		
		$task['sent'] += $task_sent;
		$task['status'] = $task_status;
		
		return $task;
	}
	
	protected function initTask($task) {
		$config = unserialize($task['config']);
		$store_id = $config['store_id'];
		switch($task['to']) {
			case 'newsletter':
				$emails = $this->db->queryArray("SELECT email FROM @@customer WHERE newsletter = 1 AND store_id = $store_id");
				break;
			case 'customer_all':
				$emails = $this->db->queryArray("SELECT email FROM @@customer WHERE store_id = $store_id");
				break;
			case 'customer_group':
				$customer_group_id = $config['customer_group_id'];
				$emails = $this->db->queryArray("SELECT email FROM @@customer WHERE customer_group_id = $customer_group_id AND store_id = $store_id");
				break;
			case 'customer':
				$customer_ids = implode(',', $config['customer']);
				$emails = $this->db->queryArray("SELECT email FROM @@customer WHERE customer_id IN ($customer_ids)");
				break;
			case 'affiliate_all':
				$emails = $this->db->queryArray("SELECT email FROM @@affiliate");
				break;
			case 'affiliate':
				$affiliate_ids = implode(',', $config['affiliate']);
				$emails = $this->db->queryArray("SELECT email FROM @@affiliate WHERE affiliate_id IN ($affiliate_ids)");
				break;
			case 'product':
				$product_ids = implode(',', $config['product']);
				$customer_ids = $this->db->queryArray("SELECT DISTINCT customer_id FROM @@order o INNER JOIN @@order_product op
						WHERE o.order_id = op.order_id AND op.product_id IN ($product_ids)");
				$customer_ids = implode(',', $customer_ids);
				$emails = $this->db->queryArray("SELECT email FROM @@customer WHERE customer_id IN ($customer_ids)");
				break;
		}
		if (!empty($emails)) {
			$data = array();
			foreach ($emails as $email) {
				$data[] = array('mail_task_id' => $task['mail_task_id'], 'email' => $email, 'status' => 0);
			}
			$this->db->insert('mail_taskitem', $data);
			return count($emails);
		}
		return 0;
	}
	
	public function getTaskItems($filter = null) {
		$sql = "SELECT* FROM @@mail_taskitem WHERE 1";
		if ($filter) {
			if ($filter->get('filter_mail_task_id')) {
				$sql .= " AND mail_task_id=" . $filter->get('filter_mail_task_id');
			}
			$sql .= $filter->sort('mail_task_id', 'DESC');
			$sql .= $filter->limit();
		}
	
		$query = $this->db->query($sql);
		return $query->rows;
	}
	
	public function getTotalTaskItems($filter = null) {
		$sql = "SELECT COUNT(*) AS total FROM @@mail_taskitem WHERE 1";
		if ($filter) {
			if ($filter->get('filter_mail_task_id')) {
				$sql .= " AND mail_task_id=" . $filter->get('filter_mail_task_id');
			}
		}
		return $this->db->queryOne($sql);
	}
}